import {
    AuthClient,
    CheckTokenReq,
    getProtoPathByRpcFunc,
    RpcFunc,
    CheckTokenRes,
    ServerPort,
} from "../common";
import { Singleton } from "../common/common/base";
import { WebSocketServer, WebSocket } from "ws";
import * as grpc from "@grpc/grpc-js";

//@ts-ignore
import root from "../common/idl/auto-gen-ws";

export class GatewayManager extends Singleton {

    static get Instance() {
        return super.GetInstance<GatewayManager>();
    }


    init() {
        const wss = new WebSocketServer({ port: 4000 });
        wss.on("connection", (ws) => {
            ws.on("error", console.error);

            ws.on("message", (buffer: Buffer) => {

                this.handleMessage(ws, buffer);

                // console.log("received:%s", buffer.toString());
            });
        });

        console.log(`Gateway服务启动!`);

    }


    /**
     * 处理 WebSocket 消息
     *
     * @param ws WebSocket 连接对象
     * @param buffer 接收到的数据缓冲区
     */
    async handleMessage(ws: WebSocket, buffer: Buffer) {
        //console.log(buffer.toString());
        const name = buffer.readUint8(0);
        const path = getProtoPathByRpcFunc(name, "req");
        const coder = root.lookup(path);
        const data = coder.decode(buffer.slice(1))
        //const { name, data } = JSON.parse(buffer.toString());

        if (name === RpcFunc.enterGame) {
            //todo: 验证玩家身份
            const res = await this.checkToken(data);
            this.sendMessage(ws, name, res);

        }
        else {
            //todo: 跟Game 进行通讯


        }


    }

    sendMessage(ws: WebSocket, name: RpcFunc, data: any) {
        const headBuffer = Buffer.alloc(1);
        headBuffer.writeUInt8(name);
        const path = getProtoPathByRpcFunc(name, "res");
        const coder = root.lookup(path);
        const dataBuffer = coder.encode(data).finish();

        const buffer = Buffer.concat([headBuffer, dataBuffer]);


        ws.send(buffer);

    }
    checkToken({ token }: { token: string }) {

        return new Promise((rs) => {
            const client = new AuthClient("localhost:3333", grpc.credentials.createInsecure());
            const req = new CheckTokenReq();
            req.setToken(token);
            client.checkToken(req, (err, massage) => {
                rs(massage.toObject());
            });
        })

    }

}